/**
 * 
 */
package info.niwota.group;

import java.util.List;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

/**
 * @author qiangli
 *
 */
public final class LocationUtils {

	private static final String TAG = "LocationUtils";

	/**
	 * 
	 */
	private LocationUtils() {
	}

	public static String getLocation(Context ctx, String defval) {
		try {
			LocationManager lm = (LocationManager) ctx
					.getSystemService(Context.LOCATION_SERVICE);
			Criteria c = new Criteria();
			//c.setAccuracy(Criteria.ACCURACY_FINE);
			c.setAltitudeRequired(false);
			c.setBearingRequired(false);
			c.setCostAllowed(true);
			c.setPowerRequirement(Criteria.POWER_LOW);
			//
			List<String> p = lm.getProviders(c, true);
			//
			Location l = null;
			for (int i = p.size() - 1; i >= 0; i--) {
				l = lm.getLastKnownLocation(p.get(i));
				if (l != null) {
					String s = formatLocation(ctx, l, defval);
					if (s != null) {
						return s;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return defval;
	}

	private static String formatLocation(Context ctx, Location l, String defval) throws Exception {
		double la = l.getLatitude();
		double lo = l.getLongitude();
		Geocoder gc = new Geocoder(ctx);
		List<Address> al = gc.getFromLocation(la, lo, 1);
		if (al == null || al.size() <= 0)  {
			return defval;
		}
		Address adr = al.get(0);
		StringBuilder sb = new StringBuilder();
		String fn = adr.getFeatureName();
		String cc = adr.getCountryCode();
		String aa = adr.getAdminArea();
		String sa = adr.getSubAdminArea();

		if (Constants.DEBUG_ENABLED) {
			Log.d(TAG, "formatLocation: " + fn + "|" + cc + "|" + aa + "|"
				+ sa);
		}
		
		String sep = ", ";
		sb.append(nvl(fn, " "));
		sb.append(nvl(sa, sep));
		sb.append(nvl(aa, sep));
		sb.append(nvl(cc, " "));
		
		return sb.toString();
	}

	private static String nvl(String s, String delimit) {
		return (s == null ? "" : s + delimit);
	}
	
	private static LocationListener locator = null;
	
	public static void registerLocationListener(final Context ctx) {
		try {
			final LocationManager lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
			locator = new LocationListener () {
					public void onLocationChanged(Location loc) {
						if (Constants.DEBUG_ENABLED) {
							Log.d(TAG, "onLocationChanged: " + loc);
						}
						lm.removeUpdates(this);
					}

					public void onProviderDisabled(String arg0) {
					}

					public void onProviderEnabled(String arg0) {
					}

					public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
					}
				};
			lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locator);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void unregisterLocationListener(final Context ctx) {
		try {
			if (locator != null) {
				LocationManager lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
				lm.removeUpdates(locator);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
